package com.leetcode.string.my_atoi;

import java.util.HashMap;
import java.util.Map;

/**
 *              ' '	    +/-	        number	    other
 * start	    start	signed	    in_number	end
 * signed	    end	    end	        in_number	end
 * in_number	end	    end	        in_number	end
 * end	        end	    end	        end	        end
 *通过该表完成对字符串的判断过程
 * 遇到空格,符号位,数字,以及其他字符的处理方式
 * 作者：LeetCode-Solution
 * 链接：https://leetcode-cn.com/problems/string-to-integer-atoi/solution/zi-fu-chuan-zhuan-huan-zheng-shu-atoi-by-leetcode-/
 * 来源：力扣（LeetCode）
 * 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
 */
public class Automaton {
    //定义三个变量
    //state 表示当前所处于的状态
    //sign 表示符号位
    //num 表示最后组成的数字
    //使用public 方便使用
    public String state = "start";
    public  int sign = 1;
    public  long num = 0;
    //定义集合用于储存上方注释中的表格
    private Map<String,String[]> map;
    //定义构造函数初始化对map存储表格的设定
    public Automaton() {
        map = new HashMap<>();
        this.map.put("start",    new String[]{"start",   "signed",   "in_number",    "end"});
        this.map.put("signed",   new String[]{"end",     "end",      "in_number",    "end"});
        this.map.put("in_number",new String[]{"end",     "end",      "in_number",    "end"});
        this.map.put("end",      new String[]{"end",     "end",      "end",          "end"});
    }
    //定义方法判断在遇到当前的字符时的处理方式
    //参数 char c
    //返回值 无
    //因为在该方法中操作成员变量,故不需要返回值
    public void get(char c){
        //state = map.get(state)[getChoice(c)];
        String[] strings = map.get(state);
        state = strings[getChoice(c)];
        if ("in_number".equals(state)){
            num = num * 10 + c - '0';//获得当前的数字
            //判断是否越界
            num = sign == 1 ?Math.min(num,(long)Integer.MAX_VALUE) :Math.min(num,-(long)Integer.MIN_VALUE);
        }else if ("signed".equals(state)){
            sign = c == '+'? 1: -1;
        }
    }
    //该方法用于对map中String类型数组数据的选择
    //参数 char c
    //返回值 int
    //需要根据不同的状态选用不同的值
    public int getChoice(char c){
        if (c == ' '){
            return 0;
        }else if (c == '+' || c =='-'){
            return 1;
        }else if (Character.isDigit(c)){//判断是否为数字
            return 2;
        }else {
            return 3;
        }
    }
}
